//
// Created by gxx on 2023/11/12.
//

#ifndef TINY_DB_LOGGER_H
#define TINY_DB_LOGGER_H

#include <mutex>
#include "base_types.h"

namespace TinyDB {

enum LOG_LEVEL {
	LOG_LEVEL_TRACE = 0,
	LOG_LEVEL_DEBUG,
	LOG_LEVEL_INFO,
	LOG_LEVEL_WARN,
	LOG_LEVEL_ERROR,
	LOG_LEVEL_FATAL,
	LOG_LEVEL_COUNT
};

enum LOG_TARGET {
	LOG_TARGET_CONSOLE = 0,
	LOG_TARGET_FILE,
	LOG_TARGET_BOTH
};

//const t_uint64 g_max_log_size = 4096;

class Logger {
 public:
	static Logger* getInstance();

	static t_void SetLogLevel(LOG_LEVEL level);
	static t_void SetLogTarget(LOG_TARGET target);

	t_void WriteLog(LOG_LEVEL log_level, const t_char* file_name, t_uint32 line, const t_char* format, ...);

 private:
	static t_string level_name_[LOG_LEVEL_COUNT];
	static Logger* instance_;
  static std::mutex mtx_;
	static std::mutex file_mtx_;
	static LOG_LEVEL log_level_;
	static t_uint8 log_target_;
	static FILE* fp_;
	static t_uint32 year_;
	static t_uint32 mouth_;
	static t_uint32 day_;

	Logger();
	~Logger();

	static FILE* GenFile();
	t_void PrintToConsole(const t_char* msg, t_uint32 n);
	t_void PrintToFile(const t_char* msg, t_uint32 n);

};



#define LOG_TRACE(fmt, ...) Logger::getInstance()->WriteLog(TinyDB::LOG_LEVEL_TRACE, __FILENAME__, __LINE__, fmt, ##__VA_ARGS__)
#define LOG_DEBUG(fmt, ...) Logger::getInstance()->WriteLog(TinyDB::LOG_LEVEL_DEBUG, __FILENAME__, __LINE__, fmt, ##__VA_ARGS__)
#define LOG_INFO(fmt, ...)  Logger::getInstance()->WriteLog(TinyDB::LOG_LEVEL_INFO, __FILENAME__, __LINE__, fmt, ##__VA_ARGS__)
#define LOG_WARN(fmt, ...)  Logger::getInstance()->WriteLog(TinyDB::LOG_LEVEL_WARN, __FILENAME__, __LINE__, fmt, ##__VA_ARGS__)
#define LOG_ERROR(fmt, ...) Logger::getInstance()->WriteLog(TinyDB::LOG_LEVEL_ERROR, __FILENAME__, __LINE__, fmt, ##__VA_ARGS__)
#define LOG_FATAL(fmt, ...) Logger::getInstance()->WriteLog(TinyDB::LOG_LEVEL_FATAL, __FILENAME__, __LINE__, fmt, ##__VA_ARGS__)


}

#endif //TINY_DB_LOGGER_H
